package org.bonorsoft.modules.dingding.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.shiro.SecurityUtils;
import org.bonorsoft.common.constant.CommonConstant;
import org.bonorsoft.common.dingapi.DingdingUser;
import org.bonorsoft.common.system.vo.LoginDingUser;
import org.bonorsoft.common.system.vo.Ztree;
import org.bonorsoft.common.util.DateUtils;
import org.bonorsoft.common.util.RedisUtil;
import org.bonorsoft.common.util.oConvertUtils;
import org.bonorsoft.modules.dingding.entity.*;
import org.bonorsoft.modules.dingding.mapper.SysDingUserMapper;
import org.bonorsoft.modules.dingding.service.*;
import org.bonorsoft.modules.dingding.vo.DingAddEntity;
import org.bonorsoft.modules.dingding.vo.UserDeptVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 钉钉用户
 * @Author: WilliamYe
 * @Date:   2020-11-13
 * @Version: V1.0
 */
@Service
public class SysDingUserServiceImpl extends ServiceImpl<SysDingUserMapper, SysDingUser> implements ISysDingUserService {

    @Autowired
    private ISysUserRoleService sysUserRoleService;

    @Autowired
    private ISysUserDepartService sysUserDepartService;

    @Autowired
    private ISysDepartService departService;

    @Autowired
    private ISysDepartLeaderService sysDepartLeaderService;

    @Autowired
    private RedisUtil redisUtil;

    @Resource
    private SysDingUserMapper sysDingUserMapper;


    @Override
    public void addOrUpdateUser(List<String> userList, String userid) {
        List<DingAddEntity> dingAddEntities = new ArrayList<>();
        List<SysDingUser> userLists = new ArrayList<>();
        for (String id:
                userList) {
            try {
                String result = DingdingUser.getUser(id);
                JSONObject obj = JSON.parseObject(result);

                DingAddEntity dingAddEntity = new DingAddEntity();
                List<SysUserDepart> departList = JSONArray.parseArray(obj.getString("dept_order_list"), SysUserDepart.class);
                List<SysDepartLeader> leaderDeptList =JSONArray.parseArray(obj.getString("leader_in_dept"), SysDepartLeader.class);
                dingAddEntity.setUserId(id);
                dingAddEntity.setSysUserDeparts(departList);
                dingAddEntity.setSysDepartLeaders(leaderDeptList);
                dingAddEntities.add(dingAddEntity);

                SysDingUser user = JSONUtil.toBean(result, SysDingUser.class);

                String deptIdList = user.getDeptIdList()
                        .replace("[","")
                        .replace("]","");
                user.setDeptIdList(deptIdList);
                String[] departs = deptIdList.split(",");
                if(departs.length == 0){
                    user.setDeptId(null);
                }else {
                    user.setDeptId(Long.parseLong(departs[0]));
                }
                user.setUpdateBy(userid);
                user.setUpdateTime(DateUtils.getDate());
                userLists.add(user);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //添加或更新用户
        this.saveOrUpdateBatch(userLists);
        //用户添加部门和部门领导信息
        saveDepartAndLeaders(dingAddEntities);
    }

    private void saveDepartAndLeaders(List<DingAddEntity> dingAddEntities) {
        for (DingAddEntity dingAdd:
                dingAddEntities) {
            List<SysUserDepart> departList = dingAdd.getSysUserDeparts();
            if(oConvertUtils.isNotEmpty(departList)){
                departList.forEach(item -> item.setUserId(dingAdd.getUserId()));
                //为用户添加部门
                saveDepart(dingAdd.getUserId(), departList);
            }

            List<SysDepartLeader> leaderDeptList = dingAdd.getSysDepartLeaders();
            if(oConvertUtils.isNotEmpty(leaderDeptList)){
                leaderDeptList.forEach(item -> item.setUserId(dingAdd.getUserId()));
                //为用户添加部门领导
                saveLeader(dingAdd.getUserId(), leaderDeptList);
            }
        }
    }

    @Override
    public void deleteUser(List<String> userList) {
        this.removeByIds(userList);
        userList.forEach(item -> {
            deleteRole(item);
            deleteDepart(item);
            deleteLeader(item);
        });
    }

    @Override
    public void updateUser(List<String> userId) {
        userId.forEach(item -> {
            String result = DingdingUser.getUser(item);
            SysDingUser user = JSONUtil.toBean(result, SysDingUser.class);
            user.setDeptIdList(user.getDeptIdList()
                    .replace("[","")
                    .replace("]",""));
            user.setUpdateTime(DateUtils.getDate());
            this.saveOrUpdate(user);
        });
    }

    /**
     * 根据手机号获取用户信息
     * @param mobile
     * @return
     */
    @Override
    public SysDingUser getUserByMobile(String mobile) {
        QueryWrapper<SysDingUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile",mobile);
        return this.getOne(queryWrapper);
    }

    /**
     * 检验用户是否激活
     * @param mobile
     * @return
     */
    @Override
    public SysDingUser getUserActiveByMobile(String mobile) {
        QueryWrapper<SysDingUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile",mobile).eq("active",1);
        return this.getOne(queryWrapper);
    }

    @Override
    public IPage<SysDingUser> selectUser(Page<SysDingUser> page, SysDingUser sysUser, Params params, HttpServletRequest request) {
        String sql = (String) request.getAttribute(CommonConstant.DATA_SCOPE);
        return sysDingUserMapper.selectUser(page,sysUser,params, sql);
    }

    /**
     * 钉钉同步用户部门信息
     * @param deptIdList
     */
    @Override
    public void synchronousUser(String deptIdList) {
        //虽然不会出现多个部门id，但是保险起见，还是转换数组取部门id，后期若影响性能，删除即可
        String deptId = deptIdList.split(",")[0];
        //获取数据库部门下全部用户信息
        List<SysDingUser> localUser = sysDingUserMapper.selectInDeptUser(deptId);
        //获取数据库部门下全部用户对应部门信息
        List<SysUserDepart> localUserDept = sysUserDepartService.getListByDeptId(deptId);
        //获取钉钉该部门下的用户
        String userList = DingdingUser.getUserList(Long.valueOf(deptIdList), 0L, 100L);
        JSONObject obj = JSON.parseObject(userList);
        List<SysDingUser> userLists = JSONArray.parseArray(obj.getString("list"), SysDingUser.class);
        List<UserDeptVo> userDeptVos = JSONArray.parseArray(obj.getString("list"), UserDeptVo.class);
        List<SysUserDepart> sysUserDepartList = new ArrayList<>();
        if(userLists.size() != 0){
            userLists.forEach(item_user -> {
                item_user.setDeptIdList(item_user.getDeptIdList()
                        .replace("[", "")
                        .replace("]", ""));
                item_user.setDeptId(Long.parseLong(deptId));
            });
            userDeptVos.forEach(item_user_dept -> {
                SysUserDepart sysUserDepart = new SysUserDepart();
                sysUserDepart.setDeptId(Long.parseLong(deptId));
                sysUserDepart.setUserId(item_user_dept.getUserid());
                sysUserDepart.setOrder(item_user_dept.getDeptOrder());
                sysUserDepartList.add(sysUserDepart);
            });
        }
        //数据库与钉钉去重 获取真正用户list-userLists
        getRealUser(localUser, userLists);
        //数据库与钉钉去重 获取真正用户与部门对应list-userDeptLists
        getRealUserDept(localUserDept, sysUserDepartList);

        if (userLists.size() > 0){
            this.saveOrUpdateBatch(userLists);
        }
        if(sysUserDepartList.size() > 0){
            sysUserDepartService.saveOrUpdateBatch(sysUserDepartList);
        }
    }

    /**
     * 根据角色id查询用户
     * @param page
     * @param sysDingUser
     * @param req
     * @return
     */
    @Override
    public IPage<SysDingUser> pageByConditions(Page<SysDingUser> page, SysDingUser sysDingUser, HttpServletRequest req) {
        String roleId = req.getParameter("roleId");
        String sql = (String) req.getAttribute(CommonConstant.DATA_SCOPE);
        return sysDingUserMapper.pageByConditions(page,sysDingUser,roleId,sql);
    }

    /**
     * 根据菜单id获取全部用户userid
     * @param menuId
     * @return
     */
    @Override
    public List<String> getAllMenuUser(Long menuId) {
        return sysDingUserMapper.getAllMenuUser(menuId);
    }

    /**
     * 根据角色id获取全部用户userid
     * @param roleId
     * @return
     */
    @Override
    public List<String> getAllRoleUser(Integer roleId) {
        return sysDingUserMapper.getAllRoleUser(roleId);
    }

    @Override
    public void updateUserDepart(String userId, Long deptId) {
        baseMapper.updateUserDepart(userId,deptId);
    }

    private void deleteRole(String userId){
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_ID",userId);
        sysUserRoleService.remove(queryWrapper);
    }

    private void saveDepart(String userId, List<SysUserDepart> departList){
        //先删除用户的所有部门
        deleteDepart(userId);
        sysUserDepartService.saveBatch(departList);
    }

    private void deleteDepart(String userId){
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_ID",userId);
        sysUserDepartService.remove(queryWrapper);
    }

    private void saveLeader(String userId, List<SysDepartLeader> leaderDeptList){
        //先删除用户的所有部门领导
        deleteLeader(userId);
        sysDepartLeaderService.saveBatch(leaderDeptList);
    }

    private void deleteLeader(String userId){
        QueryWrapper<SysDepartLeader> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_ID",userId);
        sysDepartLeaderService.remove(queryWrapper);
    }

    /**
     * 根据用户userid和unionid去重
     * @param localUser
     * @param userLists
     */
    private void getRealUser(List<SysDingUser> localUser, List<SysDingUser> userLists) {
        for (SysDingUser user : localUser) {
            userLists.removeIf(item -> (user.getUserid().equals(item.getUserid()) && user.getUnionid().equals(item.getUnionid())));
        }
        userLists.forEach(item -> {
            item.setUpdateBy(getLoginUserName());
            item.setUpdateTime(DateUtils.getDate());
        });
    }

    /**
     * 根据userid、dept_id和order去重
     * @param localUserDept
     * @param sysUserDepartList
     */
    private void getRealUserDept(List<SysUserDepart> localUserDept, List<SysUserDepart> sysUserDepartList) {
        for (SysUserDepart userDepart : localUserDept) {
            sysUserDepartList.removeIf(item -> (userDepart.getUserId().equals(item.getUserId())
                    && userDepart.getDeptId().equals(item.getDeptId())
                    && userDepart.getOrder().equals(item.getOrder())));
        }
    }

    /**
     * 获取当前登陆者姓名
     * @return
     */
    private String getLoginUserName(){
        LoginDingUser user = (LoginDingUser) SecurityUtils.getSubject().getPrincipal();
        return user.getName();
    }

    /**
     * 对象转部门用户树
     */
    public List<Ztree> initZtree(List<SysDepart> deptList, List<SysDingUser> dingUser){
        List<Ztree> ztrees = new ArrayList<Ztree>();
        for (SysDepart dept : deptList)
        {
            List<SysUserDepart> userDeparts = sysUserDepartService.getListByDeptId(Long.toString(dept.getDeptId()));
            boolean noCheck = (userDeparts.size()<1)&&(departService.notHasKidDepart(dept.getDeptId()));
            Ztree ztree = new Ztree();
            ztree.setId(dept.getDeptId());
            ztree.setpId(dept.getParentId());
            ztree.setName(dept.getName());
            ztree.setNocheck(noCheck);
            ztrees.add(ztree);
        }
        String[] ss;
        for (SysDingUser user : dingUser) {
            if(user.getDeptIdList().contains(",")){
                ss = user.getDeptIdList().split(",");
                for(int i=0;i<ss.length;i++){
                    Ztree ztree = new Ztree();
                    ztree.setId(Long.parseLong(user.getMobile()));
                    ztree.setpId(Long.parseLong(ss[i]));
                    ztree.setName(user.getName());
                    ztrees.add(ztree);
                }
            }
            else {
                Ztree ztree = new Ztree();
                ztree.setId(Long.parseLong(user.getMobile()));
                ztree.setpId(user.getDeptId());
                ztree.setName(user.getName());
                ztrees.add(ztree);
            }
        }
        return ztrees;
    }
    /**
     * 查询部门用户树
     */
    @Override
    public List<Ztree> selectDeptUserTree()
    {
        QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<>();
        QueryWrapper<SysDepart> departQueryWrapper = queryWrapper.orderByAsc("\"ORDER\"");
        List<SysDepart> departList = departService.list(departQueryWrapper);

        QueryWrapper<SysDingUser> dingUserQueryWrapper = new QueryWrapper<>();
        List<SysDingUser> dingUserList = this.list(dingUserQueryWrapper);

        List<Ztree> ztrees = initZtree(departList,dingUserList);
        return ztrees;
    }

}
